#include "02_TaskQueue.hpp"
#include "05_Producer.hpp"

TaskQueue::TaskQueue(int list_max_size, int list_init_size)
//    :_list(new queue<int> que)
    :_list(list<int>())
    ,_list_max_size(list_max_size)
    ,_list_init_size(list_init_size)
    ,_mutex()
    ,_notfull()
    ,_notempty()
{
    Producer::init(*this);    // C++ 不允许*和&相互转换，我第一次看到这种错误...
    //Producer::init(&this);  // this已经是指针，*this传递的是**
}

//TaskQueue::TaskQueue(int que_size) = default;

bool TaskQueue::empty()
{
    return _list.size() == 0;
}

bool TaskQueue::full()
{
    return static_cast<int>(_list.size()) == _list_max_size;
}

void TaskQueue::push(int data)
{
    //_mutex.lock();
    Mutex::LockGuard lock(_mutex);

    while(full())
    {
        _notfull.wait(_mutex);
    }

    _list.push_back(data);
    
    //_notfull.notify_one();
    _notempty.notify_one();

    //_mutex.unlock();
}

int TaskQueue::pop()
{
    //_mutex.lock();
    Mutex::LockGuard lock(_mutex);

    while(empty())
    {
        _notempty.wait(_mutex);
    }

    int data = _list.front();
    _list.pop_front();

    //_notfull.notify_one();
    _notfull.notify_one();

    return data;
}

int TaskQueue::get_list_init_size()
{
    return _list_init_size;
}
